#coding=utf-8
'''
Created on 2017-04-26

@author: sandy
'''

from twisted.internet import task
import logging
from pycommon import Const,DbPool,Utils
import ClientBuild
from pycommon import RedisDb
import ClientFactory
import GateInfo


class GameDB(object):
    def __init__(self):
        self.__linkcount = 0
        self.__dbp = None
    def start(self,db,user,passwd,host = u'127.0.0.1',port = 3306,linkcount = 3):
        logging.info("GameDb host=%s db=%s user=%s",host,db,user)
        l = task.LoopingCall(self.onTimer)
        l.start(10, False)
        self.__linkcount = linkcount
        self.__dbp = DbPool.DBConnectionPool(db = db,user = user,passwd = passwd,host = host,port = port,linkcount = linkcount)
        self.__dbp.start()
        

    def stop(self):
        self.__dbp.stop()
        
    def onTimer(self):
        self.doTask()
    
    def doTask(self):
        pass
            
    def hashIndex(self, uid):
        return uid % self.__linkcount
    
    def hashIndexAccount(self, account):
        return ord(account[0]) % self.__linkcount  
    
    def query(self, conindex, ctx, sql, params, func):
        self.__dbp.query(conindex, ctx, sql, params, func)

    def execute(self, conindex, ctx, sql, params, func):
        self.__dbp.execute(conindex, ctx, sql, params, func)
################################################################ HTTP #########################################
    def loginHTTP(self, uid,account,cbk):
        logging.debug("GameDb login")
        sql = u"call p_login(%s, %s)"
        params = (uid,account)
        ctx = (uid,account, cbk)
        self.query(self.hashIndexAccount(account),ctx,sql,params,self.loginResultHTTP)

    def loginResultHTTP(self, ctx, error, rows):
        uId,account,cbk = ctx
        if error:
            logging.error(u"GameDb loginResult() FAIL, account=%s err=%s", account, error)
            cbk(0,uId)
            return
        logging.debug("GameDb loginResult")
        ret = int(rows[0][0])
        if ret != Const.ERR_OK:
            logging.debug(u"pUID=%d,aUID=%d登陆失败 ret=%d",uId,uid,ret)
            cbk(ret,uId)
        else:
            uid = int(rows[0][1])
            logging.debug(u"pUID=%d,aUID=%d登陆成功 ret=%d",uId,uid,ret)
            cbk(ret,uid)
        

    def registerHTTP(self, uid,account,cbk):
        logging.debug("GameDb register")
        sql = u"call p_register(%s, %s)"
        params = (account, uid)
        ctx = (account, uid,cbk)
        self.query(self.hashIndexAccount(account),ctx,sql,params,self.registerResultHTTP)

    def registerResultHTTP(self, ctx, error, rows):
        account,uId,cbk = ctx
        if error:
            logging.error(u"GameDb registerHTTP FAIL, account=%s err=%s", account, error)
            cbk(0)
            return
        logging.debug("GameDb registerResultHTTP")
        ret = int(rows[0][0])
        if ret != Const.ERR_OK:
            logging.debug(u"pUID=%d 注册失败 ret=%d",uId,ret)
        else:
            uid = int(rows[0][1])
            logging.debug(u"pUID=%d,aUID%d注册成功 ret=%d",uId,uid,ret)
        cbk(ret)    
#####################################################################  TCP ###################################
    def login(self,client,uid,account):
        logging.debug(u"GameDb login account=%s,uid=%d",account,uid)
        sql = u"call p_login(%s, %s)"
        params = (uid,account)
        ctx = (client,uid,account)
        self.query(self.hashIndexAccount(account),ctx,sql,params,self.loginResult)
        
    def loginResult(self, ctx, error, rows):
        client,uId,account = ctx
        if error:
            logging.error(u"GameDb loginResult() FAIL, account=%s err=%s", account, error)
            return
        logging.debug(u"GameDb loginResult")
        ret = int(rows[0][0])
        if ret != Const.ERR_OK:
            logging.error(u"GameDb loginResult() FAIL, ret = %d", ret)
            client.sendPacket(ClientBuild.loginResult(ret,u'',u''))
        else:
            uid = int(rows[0][1])
            client.onLogin(uid)
            logging.debug(u"pUID=%d,aUID=%d LoinSucess ret=%d",uId,uid,ret)
            session = str(Utils.genSession())
            redisSession = Utils.md5sumhex(str(uid)+"USERSESSION"+session)
            RedisDb.instance.addUserSession(uid,redisSession)
            logging.debug("uid=%d session=%s redisSession=%s",uid,session,redisSession)
            #gateJson = RedisDb.instance.getGateInfo()
            gateJson = GateInfo.instance.getSuitableGateJsonInfo()
            #通知客户端基本信息
            client.sendPacket(ClientBuild.loginResult(ret,uid,session))
            client.sendPacket(ClientBuild.gateInfo(ret,gateJson))
            
    def loginWeChat(self,cid,nickname,headimgurl,sex,openid,unionid):
        logging.debug(u"GameDb loginWeChat cid=%d,nickname=%s,headimgurl=%s,sex=%d,openid=%s,unionid=%s",cid,nickname,headimgurl,sex,openid,unionid)
        sql = u"call p_login_wechat(%s, %s)"
        params = (openid,unionid)
        ctx = (cid,nickname,headimgurl,sex,openid,unionid)
        logging.debug("hashIndex:%d",self.hashIndex(cid))
        self.query(self.hashIndex(cid),ctx,sql,params,self.loginWeChatResult)
        pass

    def loginWeChatResult(self, ctx, error, rows):
        cid,nickname,headimgurl,sex,openid,unionid = ctx
        if error:
            logging.error(u"GameDb loginResult() FAIL, account=%s err=%s", account, error)
            return
        uid = rows[0][0]
        session = str(Utils.genSession())
        redisSession = Utils.md5sumhex(str(uid)+"USERSESSION"+str(session))
        RedisDb.instance.addUserSession(uid,redisSession)
        client = ClientFactory.instance.getProtocol(cid)
        gateJson = GateInfo.instance.getSuitableGateJsonInfo()
        logging.debug("gateJson = %s",gateJson)
        if client:
            client.onLogin(uid)
            client.sendPacket(ClientBuild.loginResult(Const.ERR_OK,uid,session))
            client.sendPacket(ClientBuild.loginWeChatResult(nickname,headimgurl,sex))
            client.sendPacket(ClientBuild.gateInfo(Const.ERR_OK,gateJson))
        else:
            logging.debug("loginWeChatResult pid=%d client is None",cid)
        pass

    def register(self,client,uid,account):
        logging.debug("GameDb register")
        sql = u"call p_register(%s, %s)"
        params = (account, uid)
        ctx = (client,account, uid)
        self.query(self.hashIndexAccount(account),ctx,sql,params,self.registerResult)

    def registerResult(self, ctx, error, rows):
        client,account,uId = ctx
        if error:
            logging.error(u"GameDb registerResult() FAIL, account=%s err=%s", account, error)
            return
        logging.debug("GameDb registerResult")
        ret = int(rows[0][0])
        if ret != Const.ERR_OK:
            logging.debug(u"pUID=%d 注册失败 ret=%d",uId,ret)
        else:
            uid = int(rows[0][1])
            logging.debug(u"pUID=%d,aUID=%d注册成功 ret=%d",uId,uid,ret)   
        client.sendPacket(ClientBuild.registerResult(ret))

instance = GameDB()

if __name__ == '__main__':
    pass